package com.huike.service;

import com.huike.dao.GroupDAO;
import com.huike.dao.SysCustomDAO;
import com.huike.dao.UserDAO;
import com.huike.po.*;
import com.huike.pojo.GroupCustomBean;
import com.huike.pojo.MsgUpdateObject;
import com.huike.pojo.SystemCustomObject;
import com.huike.websocket.ChatWebSocketHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.sql.rowset.serial.SerialBlob;
import java.io.IOException;
import java.sql.Blob;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

@Service
public class GroupServiceImpl implements GroupService{
    @Autowired
    private GroupDAO groupDAO;
    @Autowired
    private ChatWebSocketHandler webSocket;
    @Autowired
    private MsgUpdateObject msgUpdateObject;
    @Autowired
    private SystemCustom systemCustom;
    @Autowired
    SystemCustomObject systemCustomObject;
    @Autowired
    private SysCustomDAO sysCustomDAO;
    @Autowired
    private UserDAO userDAO;
    @Override
    public List<GroupMessage> getChatRecord(String groupId) {
        List<GroupMessage> groupMessageList = groupDAO.selectGroupChatRecordById(groupId);
        return groupMessageList;
    }

    @Override
    public List<GroupMessage> getRoamingRecord(String groupId) {
        List<GroupMessage> groupMessageList = groupDAO.selectGroupRoamingRecordById(groupId);
        return groupMessageList;
    }

    @Override
    public List<GroupMember> getGroupMembersByGroupId(String groupId) {
        List<GroupMember> groupMemberList = groupDAO.selectGroupMemberById(groupId);
        return groupMemberList;
    }

    @Override
    public boolean deleteOfflineMsg(String userAccount, String groupId) {
        try{
            groupDAO.deleteOfflineGroupRecord(userAccount,groupId);
            return true;
        }catch (Exception e){
            return false;
        }

    }

    @Override
    public boolean isMuted(String account, String groupId) {
        List<GroupMember> memberList = groupDAO.selectGroupMemberByAccountAndGroupId(account, groupId);
        if (memberList.size() == 0) {
            return false;
        }
        if (memberList.get(0).getIs_muted() == 1)
            return true;
        else
            return false;
    }
    @Override
    public boolean sendMessage(GroupMessage message) {
        if (isMuted(message.getMsgFrom(), message.getGroupId())) {
            return false;
        }
        switch (message.getMsgType()) {
            case "text" :
                message.setMsgTypeId(1);
                break;
            case "file" :
                message.setMsgTypeId(2);
                break;
            case "image" :
                message.setMsgTypeId(3);
                break;
            case "audio" :
                message.setMsgTypeId(4);
                break;
        }

        groupDAO.insertGroupChatRecord(message);

        List<User> userList = groupDAO.selectUsersByGroupId(message.getGroupId());

        if(userList.size() > 0) {
            msgUpdateObject.setUpdateType("UpdateGroupMessage");
            msgUpdateObject.setUpdateContent(message);
            msgUpdateObject.setUpdateFrom(message.getMsgFrom());
            webSocket.sendUpdateToGroup(msgUpdateObject, userList);
        }

        return true;
    }


    @Override
    public boolean addManager(GroupMember groupMember) {
        groupMember.setRoleId(2);
        groupDAO.updateGroupMemberRole(groupMember);
        //向被设置管理员的人发送消息

        return true;
    }

    @Override
    public boolean delManager(GroupMember groupMember) {
        groupMember.setRoleId(3);
        groupDAO.updateGroupMemberRole(groupMember);
        //向被解除管理员的人发送消息

        return true;
    }

    @Override
    public boolean muteMember(GroupMember groupMember) {
        groupMember.setIs_muted(1);
        groupDAO.updateGroupMemberIs_mute(groupMember);
        return true;
    }

    @Override
    public boolean unmuteMember(GroupMember groupMember) {
//        List<GroupMember> memberList= groupDAO.selectGroupMemberByAccountAndGroupId(groupMember.getAccount(), groupMember.getGroupId());
//        if(memberList.size() == 0)
//            groupMember = memberList.get(0);
//        else
//            return false;
        groupMember.setIs_muted(0);
        groupDAO.updateGroupMemberIs_mute(groupMember);
        return true;
    }

    @Override
    public boolean unmuteAllMember(GroupBasic groupBasic) {
        groupDAO.setAllGroupMemberIs_mute(groupBasic.getGroupId(), 0);
        return true;
    }

    @Override
    public boolean muteAllMember(GroupBasic groupBasic) {
        groupDAO.setAllGroupMemberIs_mute(groupBasic.getGroupId(), 1);
        return true;
    }

    @Override
    public boolean handleGroup(GroupCustomBean groupRequest, String type) {
        // 插入群聊相关的系统通知
        switch (type) {
            case "GroupInvite":
                systemCustom.setSctype_id(4);
                systemCustomObject.setSysCustomContent("GroupInvite");
                systemCustomObject.setReservedFields("");
                break;
            case "agreeGroupInvite":
                // 同意群邀请不需要向接收方发送实时通知
                systemCustom.setSctype_id(5);
                systemCustomObject.setSysCustomContent("agreeGroupInvite");
                systemCustomObject.setReservedFields("");
                // 标记原有的申请通知为已处理
                sysCustomDAO.updateSysCustomToBeHandled(groupRequest.getHandledSysId(), "您已同意了入群邀请");
                break;
            case "refuseGroupInvite":
                systemCustom.setSctype_id(6);
                systemCustomObject.setSysCustomContent("refuseGroupInvite");
                systemCustomObject.setReservedFields("");
                // 标记原有的申请通知为已处理
                sysCustomDAO.updateSysCustomToBeHandled(groupRequest.getHandledSysId(), "您已拒绝了入群邀请");
                break;
            case "applyGroup":
                systemCustom.setSctype_id(9);
                systemCustomObject.setSysCustomContent("applyGroup");
                systemCustomObject.setReservedFields("");
                break;
            case "agreeApplyGroup":
                systemCustom.setSctype_id(10);
                systemCustomObject.setSysCustomId(groupRequest.getHandledSysId());
                systemCustomObject.setSysCustomContent("agreeApplyGroup");
                // 标记原有的申请通知为已处理
                sysCustomDAO.updateSysCustomToBeHandled(groupRequest.getHandledSysId(), "已同意入群");
                break;
            case "refuseApplyGroup":
                systemCustom.setSctype_id(11);
                systemCustomObject.setSysCustomId(groupRequest.getHandledSysId());
                systemCustomObject.setSysCustomContent("refuseApplyGroup");
                systemCustomObject.setReservedFields("");
                // 标记原有的申请通知为已处理
                sysCustomDAO.updateSysCustomToBeHandled(groupRequest.getHandledSysId(), "已拒绝入群");
                break;
        }
        // 设置数据库存储的po实体内容，from、groupId
        systemCustom.setSyscustom_from(groupRequest.getAccountFrom());
        systemCustom.setGroup_id(groupRequest.getGroupId());

        // 设置websocket传输的通知实体内容
        UserDetail userFrom = userDAO.selectUserDetailByAccount(groupRequest.getAccountFrom());
        systemCustomObject.setSysCustomType("GroupCustom");
        systemCustomObject.setSysCustomFrom(userFrom);
        systemCustomObject.setSysCustomTime(groupRequest.getSendTime());

        if(type.equals("applyGroup") || type.equals("agreeApplyGroup") || type.equals("refuseApplyGroup")){
            // 这三种类型，groupRequest不存在accountTo
            List<User> managerList = groupDAO.selectManagersByGroupId(groupRequest.getGroupId());
            for(User user : managerList){
                systemCustom.setSyscustom_to(user.getAccount());
                sysCustomDAO.insertGroupSysCustom(systemCustom);
            }
            webSocket.sendSysCustomToUsers(systemCustomObject, managerList);
        }
        else if(type.equals("GroupInvite") || type.equals("agreeGroupInvite") || type.equals("refuseGroupInvite")){
            // 这三种类型，groupRequest中的accountTo是存在的
            systemCustom.setSyscustom_to(groupRequest.getAccountTo());
            sysCustomDAO.insertGroupSysCustom(systemCustom);
            webSocket.sendSysCustomToUser(systemCustomObject, groupRequest.getAccountTo());
        }
        return true;
    }

    @Override
    public GroupDetail findGroup(String groupId) {
        List<GroupDetail> groupList = groupDAO.findGroupById(groupId);
        if(groupList.size() == 0)
            return null;
        return groupList.get(0);
    }

    @Override
    public List<GroupMessage> getFileRecord(String groupId) {
        List<GroupMessage> groupFileList = groupDAO.selectGroupMessageByIdAndType(groupId, "file");
        return groupFileList;
    }

    /*
     * 建一个新的群/讨论组
     */
    @Override
    public GroupDetail createGroup(GroupIdAndAccouts groupIdAndAccouts) {
        if(groupIdAndAccouts.getGroupType() == 0)
            groupIdAndAccouts.setGroupType(1);//如果没有指定群种类就创建讨论组

        GroupWithOwnerAccount ga = new GroupWithOwnerAccount();
        ga.setAccount(groupIdAndAccouts.getAccountFrom());
        ga.setGroupType(groupIdAndAccouts.getGroupType());
        int groupId = groupDAO.getMaxGroupId() + 1; // 获取群号
        ga.setGroupId(groupId);
        // 创建群聊
        groupDAO.createGroupByAccountAndGroupType(ga);
        // 获取群聊详细信息
        GroupDetail group =this.findGroup(String.valueOf(groupId));

        List<String> accounts = groupIdAndAccouts.getAccounts();
        int groupType = groupIdAndAccouts.getGroupType();
        if(groupType == 1) { //讨论组
            int siz = accounts.size();
            for(int i = 0; i < siz; ++ i) {
                GroupMember gm = new GroupMember();
                gm.setGroupId(String.valueOf(groupId));
                gm.setAccount(accounts.get(i));
                int isInGroup = groupDAO.getIsInGroupByGroupIdAndAccount(gm);
                if(isInGroup != 0) continue; // 在群里就不重复添加了
                groupDAO.addMemberByGroupIdAndAccount(gm);
            }
        }
        else if(groupType == 2){ //高级群
            systemCustom.setSyscustom_from(groupIdAndAccouts.getAccountFrom());
            systemCustom.setSctype_id(4);
            systemCustom.setGroup_id(String.valueOf(groupId));

            List<User> userList = new ArrayList<>();
            for(String acc : accounts) {
                User tmpuser = new User();
                tmpuser.setAccount(acc);
                userList.add(tmpuser);
                // 向数据库中插入消息记录
                systemCustom.setSyscustom_to(acc);
                sysCustomDAO.insertInviteGroupSysCustom(systemCustom);
            }

            UserDetail userFrom = userDAO.selectUserDetailByAccount(groupIdAndAccouts.getAccountFrom());
            systemCustomObject.setSysCustomFrom(userFrom);
            systemCustomObject.setSysCustomType("GroupCustom");
            systemCustomObject.setSysCustomContent("teamInvite");
            systemCustomObject.setSysCustomTime(groupIdAndAccouts.getCreateTime());
            systemCustomObject.setReservedFields(group);//在保留字段中放入新的群聊
            webSocket.sendSysCustomToUsers( systemCustomObject,userList);
        }

        return group;
    }

    @Override
    public boolean inviteMember(GroupIdAndAccouts groupIdAndAccouts){
        String groupId = groupIdAndAccouts.getGroupId();
        List<String> accounts = groupIdAndAccouts.getAccounts();

        //获取群种类
        int groupType = groupDAO.getGroupTypeByGroupId(groupId);

        int roleType = -1;
        if (!groupIdAndAccouts.getAccountFrom().equals("")){
            //获取发起请求的人的群内身份
            GroupMember rolegm = new GroupMember();
            rolegm.setAccount(groupIdAndAccouts.getAccountFrom());
            rolegm.setGroupId(groupIdAndAccouts.getGroupId());
            roleType = groupDAO.getGMRoleIdByGroupIdAndAccount(rolegm);
        }


        if(groupType == 1 || roleType == 1|| roleType == 2) { // 是讨论组或邀请人是管理或群主，直接加人
            int siz = accounts.size();
            for(int i = 0; i < siz; ++ i) {
                GroupMember gm = new GroupMember();
                gm.setGroupId(groupId);
                gm.setAccount(accounts.get(i));
                int isInGroup = groupDAO.getIsInGroupByGroupIdAndAccount(gm);
                if(isInGroup != 0) continue; // 在群里就不重复添加了
                groupDAO.addMemberByGroupIdAndAccount(gm);
            }
        }
        else { // 向这些人发消息是否同意入群, (并向群主或管理发消息请求入群,这个是后面处理
            SystemCustom systemCustom = new SystemCustom(); // 新建系统通知消息类型
            systemCustom.setSyscustom_from(groupIdAndAccouts.getAccountFrom());
            systemCustom.setSctype_id(4);
            systemCustom.setGroup_id(groupId);

            List<User> userList = new ArrayList<>();
            for(String acc : accounts) {
                User tmpuser = new User(acc, "", "");
                userList.add(tmpuser);
                //向数据库中插入消息记录
                systemCustom.setSyscustom_to(acc);
                sysCustomDAO.insertInviteGroupSysCustom(systemCustom);
            }
            SystemCustomObject systemCustomObject = new SystemCustomObject();

            UserDetail userDetail = new UserDetail();
            userDetail.setAccount(groupIdAndAccouts.getAccountFrom());
            systemCustomObject.setSysCustomFrom(userDetail); //谁邀请的
            systemCustomObject.setSysCustomType("4");// 种类是邀请进群
            systemCustomObject.setSysCustomContent(groupIdAndAccouts.getAccountFrom() +"邀请您进入群" + groupId);
            systemCustomObject.setReservedFields(groupId);//在保留字段中放入群号



            webSocket.sendSysCustomToUsers( systemCustomObject,userList);
        }

        return true;
    }

    @Override
    public boolean deleteMember(GroupIdAndAccouts groupIdAndAccouts) {
        String groupId = groupIdAndAccouts.getGroupId();
        List<String> accounts = groupIdAndAccouts.getAccounts();

        //获取发起请求的人的群内身份
        GroupMember rolegm = new GroupMember();
        rolegm.setAccount(groupIdAndAccouts.getAccountFrom());
        rolegm.setGroupId(groupId);
        int roleType = groupDAO.getGMRoleIdByGroupIdAndAccount(rolegm);

        if(roleType == 3) return false; // 只有管理和群主才能删人

        // 获取这个群的所有群成员并封装进user的list里
        List<GroupMember> groupMemberList = groupDAO.selectGroupMemberById(groupId);
        List<User> userList = new ArrayList<>();
        for(GroupMember gm : groupMemberList) {
            User tmpuser = new User(gm.getAccount(),"","");
            userList.add(tmpuser);
        }
        // 为避免反复获取list, 不调用上面已有的sendMessage

        GroupMessage groupMessage = new GroupMessage();
        groupMessage.setGroupId(groupId);
        groupMessage.setMsgType("1"); // text类型消息

        int siz = accounts.size();
        for(int i = 0; i < siz; ++ i) {
            GroupMember tmpgm = new GroupMember();
            tmpgm.setAccount(groupIdAndAccouts.getAccountFrom());
            tmpgm.setGroupId(groupId);
            int roletmp = groupDAO.getGMRoleIdByGroupIdAndAccount(tmpgm);
            if(roleType == 1 && roletmp == 1) continue; // 群主不能删群主
            if(roleType == 2 && roletmp != 3) continue; // 管理只能删普通成员

            GroupMember gm = new GroupMember();
            gm.setGroupId(groupId);
            gm.setAccount(accounts.get(i));
            if(groupDAO.deleteMemberByGroupIdAndAccount(gm)){ // 如果删成功, 发一条群消息
                groupMessage.setMsgContent(accounts.get(i) + "已退出群聊");
                groupDAO.insertGroupChatRecord(groupMessage); // 向群聊记录数据库中插入一条消息
                msgUpdateObject.setUpdateType("UpdateGroupMessage");
                msgUpdateObject.setUpdateContent(accounts.get(i) + "已退出群聊");
                msgUpdateObject.setUpdateFrom("");
                webSocket.sendUpdateToGroup(msgUpdateObject, userList);
            }

        }
        return true;
    }

    @Override
    public boolean exitGroup(GroupWithOwnerAccount groupWithOwnerAccount) {
        int groupId = groupWithOwnerAccount.getGroupId();
        String account = groupWithOwnerAccount.getAccount();
        GroupMember gm = new GroupMember();
        gm.setAccount(account);
        gm.setGroupId(String.valueOf(groupId));
        groupDAO.addMemberByGroupIdAndAccount(gm);
        return true;
    }

    Blob getBlob(MultipartFile file) {
        Blob blob = null;
        try {
            blob = new SerialBlob(file.getBytes());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } catch (IOException e) {
            System.out.println("file to blob error.");
            e.printStackTrace();
        }

        return blob;
    }

    @Override
    public boolean sendFile(GroupFileMsg message, MultipartFile file) {
        if (isMuted(message.getMsgFrom(), message.getGroupId())) {
            return false;
        }

        message.setFileContent(getBlob(file));

        System.out.println(message.getFileContent());

        groupDAO.insertGroupFileRecord(message);

        List<User> userList = groupDAO.selectUsersByGroupId(message.getGroupId());

        if(userList.size() > 0) {
            msgUpdateObject.setUpdateType("UpdateGroupMessage");
            msgUpdateObject.setUpdateContent(message);
            msgUpdateObject.setUpdateFrom(message.getMsgFrom());
            webSocket.sendUpdateToGroup(msgUpdateObject, userList);
        }

        return true;
    }

    @Override
    public byte[] getFile(String groupId, String fileName) {
        List<GroupFileMsg> message = groupDAO.selectFileByGroupIdAndFileName(groupId, fileName);
        if(message.size() == 0)
            return null;
        byte[] file = (byte[]) message.get(0).getFileContent();
        return file;
    }

    @Override
    public List<GroupFileMsg> getFileList(String groupId) {
        List<GroupFileMsg> message = groupDAO.selectGroupFileRecordById(groupId);
        for(GroupFileMsg item : message) {
            System.out.println(item.getMsgContent());
        }
        return message;
    }

}
